using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing.Design;
using System.Windows.Forms.Design;
using System.Security;
using System.Security.Permissions;
using System.ComponentModel;

namespace AntEater.ComponentModel.BuildElements.Design
{

    /// <summary>
    /// Provides a <c>UITypeEditor</c> for editing multi line strings.
    /// </summary>
    public class TextTypeEditor : UITypeEditor
    {

        private IWindowsFormsEditorService _editorService;

        /// <summary>
        /// Gets or sets the editor service.
        /// </summary>
        /// <value>The editor service.</value>
        public IWindowsFormsEditorService EditorService {
            get { return _editorService; }
            set { _editorService = value; }
        }


        /// <summary>
        /// Edits the specified object's value using the editor style indicated by the <see cref="M:System.Drawing.Design.UITypeEditor.GetEditStyle"></see> method.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that can be used to gain additional context information.</param>
        /// <param name="provider">An <see cref="T:System.IServiceProvider"></see> that this editor can use to obtain services.</param>
        /// <param name="value">The object to edit.</param>
        /// <returns>
        /// The new value of the object. If the value of the object has not changed, this should return the same object it was passed.
        /// </returns>
        [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
        public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) {

            if (context == null) { throw new ArgumentNullException("context"); }
            if (provider == null) { throw new ArgumentNullException("provider"); }

            string propertyValue = value as string;

            this.EditorService = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;

            if (this.EditorService != null) {

                IBuildElement buildElement = context.Instance as IBuildElement;

                if (buildElement != null) {
                    TextTypeEditorUI uiComponent = new TextTypeEditorUI(propertyValue);

                    uiComponent.EditComplete += new EventHandler(EditComplete);

                    this.EditorService.DropDownControl(uiComponent);

                    propertyValue = uiComponent.PropertyValue;
                }
            }

            return propertyValue;
        }

        /// <summary>
        /// Edits the complete.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void EditComplete(object sender, EventArgs e) {
            this.EditorService.CloseDropDown();
        }

        /// <summary>
        /// Gets the editor style used by the <see cref="M:System.Drawing.Design.UITypeEditor.EditValue(System.IServiceProvider,System.Object)"></see> method.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that can be used to gain additional context information.</param>
        /// <returns>
        /// A <see cref="T:System.Drawing.Design.UITypeEditorEditStyle"></see> value that indicates the style of editor used by the <see cref="M:System.Drawing.Design.UITypeEditor.EditValue(System.IServiceProvider,System.Object)"></see> method. If the <see cref="T:System.Drawing.Design.UITypeEditor"></see> does not support this method, then <see cref="M:System.Drawing.Design.UITypeEditor.GetEditStyle"></see> will return <see cref="F:System.Drawing.Design.UITypeEditorEditStyle.None"></see>.
        /// </returns>
        [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
        public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context) {
            return UITypeEditorEditStyle.DropDown;
        }

        /// <summary>
        /// Indicates whether the specified context supports painting a representation of an object's value within the specified context.
        /// </summary>
        /// <param name="context">An <see cref="T:System.ComponentModel.ITypeDescriptorContext"></see> that can be used to gain additional context information.</param>
        /// <returns>
        /// true if <see cref="M:System.Drawing.Design.UITypeEditor.PaintValue(System.Object,System.Drawing.Graphics,System.Drawing.Rectangle)"></see> is implemented; otherwise, false.
        /// </returns>
        [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
        public override bool GetPaintValueSupported(System.ComponentModel.ITypeDescriptorContext context) {
            return false;
        }

        /// <summary>
        /// Gets a value indicating whether drop-down editors should be resizable by the user.
        /// </summary>
        /// <value></value>
        /// <returns>true if drop-down editors are resizable; otherwise, false. </returns>
        public override bool IsDropDownResizable {
            [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
            get { return true; }
        }
    }
}
